home *** CD-ROM | disk | FTP | other *** search
/ Internet Surfer 2.0 / Internet Surfer 2.0 (Wayzata Technology) (1996).iso / pc / text / mac / faqs.433 < prev    next >
Text File  |  1996-02-12  |  28KB  |  844 lines

  1. Frequently Asked Questions (FAQS);faqs.433
  2.  
  3.  
  4.  
  5.     But if you're bound and determined, you can use the multi-dimensional
  6.     array emulation of $a{'x','y','z'}, or you can make an array of names
  7.     of arrays and eval it.
  8.  
  9.     For example, if @name contains a list of names of arrays, you can
  10.     get at a the j-th element of the i-th array like so:
  11.  
  12.     $ary = $name[$i];
  13.     $val = eval "\$$ary[$j]";
  14.  
  15.     or in one line
  16.  
  17.     $val = eval "\$$name[$i][\$j]";
  18.  
  19.     You could also use the type-globbing syntax to make an array of *name
  20.     values, which will be more efficient than eval.  Here @name hold
  21.     a list of pointers, which we'll have to dereference through a temporary
  22.     variable.
  23.  
  24.     For example:
  25.  
  26.     { local(*ary) = $name[$i]; $val = $ary[$j]; }
  27.  
  28.     In fact, you can use this method to make arbitrarily nested data
  29.     structures.  You really have to want to do this kind of thing
  30.     badly to go this far, however, as it is notationally cumbersome.
  31.  
  32.     Let's assume you just simply *have* to have an array of arrays of
  33.     arrays.  What you do is make an array of pointers to arrays of
  34.     pointers, where pointers are *name values described above.  You
  35.     initialize the outermost array normally, and then you build up your
  36.     pointers from there.  For example:
  37.  
  38.     @w = ( 'ww' .. 'xx' );
  39.     @x = ( 'xx' .. 'yy' );
  40.     @y = ( 'yy' .. 'zz' );
  41.     @z = ( 'zz' .. 'zzz' );
  42.  
  43.     @ww = reverse @w;
  44.     @xx = reverse @x;
  45.     @yy = reverse @y;
  46.     @zz = reverse @z;
  47.  
  48.     Now make a couple of array of pointers to these:
  49.  
  50.     @A = ( *w, *x, *y, *z );
  51.     @B = ( *ww, *xx, *yy, *zz );
  52.  
  53.     And finally make an array of pointers to these arrays:
  54.  
  55.     @AAA = ( *A, *B );
  56.  
  57.     To access an element, such as AAA[i][j][k], you must do this:
  58.  
  59.     local(*foo) = $AAA[$i];
  60.     local(*bar) = $foo[$j];
  61.     $answer = $bar[$k];
  62.  
  63.     Similar manipulations on associative arrays are also feasible.
  64.  
  65.     You could take a look at recurse.pl package posted by Felix Lee
  66.     <flee@cs.psu.edu>, which lets you simulate vectors and tables (lists and
  67.     associative arrays) by using type glob references and some pretty serious
  68.     wizardry.
  69.  
  70.     In C, you're used to creating recursive datatypes for operations
  71.     like recursive decent parsing or tree traversal.  In Perl, these
  72.     algorithms are best implemented using associative arrays.  Take an
  73.     array called %parent, and build up pointers such that $parent{$person}
  74.     is the name of that person's parent.  Make sure you remember that
  75.     $parent{'adam'} is 'adam'. :-) With a little care, this approach can
  76.     be used to implement general graph traversal algorithms as well.
  77.  
  78.  
  79. 2.10) How can I quote a variable to use in a regexp?
  80.  
  81.     From the manual:
  82.  
  83.     $pattern =~ s/(\W)/\\$1/g;
  84.  
  85.     Now you can freely use /$pattern/ without fear of any unexpected
  86.     meta-characters in it throwing off the search.  If you don't know
  87.     whether a pattern is valid or not, enclose it in an eval to avoid
  88.     a fatal run-time error.
  89.  
  90.  
  91. 2.11) Why do setuid Perl scripts complain about kernel problems?
  92.  
  93.     This message:
  94.  
  95.     YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!
  96.     FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!
  97.  
  98.     is triggered because setuid scripts are inherently insecure due to a
  99.     kernel bug.  If your system has fixed this bug, you can compile Perl
  100.     so that it knows this.  Otherwise, create a setuid C program that just
  101.     execs Perl with the full name of the script.
  102.  
  103.  
  104. 2.12) How do I open a pipe both to and from a command?
  105.  
  106.     In general, this is a dangerous move because you can find yourself in a
  107.     deadlock situation.  It's better to put one end of the pipe to a file.
  108.     For example:
  109.  
  110.     # first write some_cmd's input into a_file, then
  111.     open(CMD, "some_cmd its_args < a_file |");
  112.     while (<CMD>) {
  113.  
  114.     # or else the other way; run the cmd
  115.     open(CMD, "| some_cmd its_args > a_file");
  116.     while ($condition) {
  117.         print CMD "some output\n";
  118.         # other code deleted
  119.     }
  120.     close CMD || warn "cmd exited $?";
  121.  
  122.     # now read the file
  123.     open(FILE,"a_file");
  124.     while (<FILE>) {
  125.  
  126.     If you have ptys, you could arrange to run the command on a pty and
  127.     avoid the deadlock problem.  See the chat2.pl package in the
  128.     distributed library for ways to do this.
  129.  
  130.     At the risk of deadlock, it is theoretically possible to use a
  131.     fork, two pipe calls, and an exec to manually set up the two-way
  132.     pipe.  (BSD system may use socketpair() in place of the two pipes,
  133.     but this is not as portable.)  The open2 library function distributed
  134.     with the current perl release will do this for you.
  135.  
  136.     It assumes it's going to talk to something like adb, both writing to
  137.     it and reading from it.  This is presumably safe because you "know"
  138.     that commands like adb will read a line at a time and output a line at
  139.     a time.  Programs like sort that read their entire input stream first,
  140.     however, are quite apt to cause deadlock.
  141.  
  142.  
  143. 2.13) How can I change the first N letters of a string?
  144.  
  145.     Remember that the substr() function produces an lvalue, that is, it may be
  146.     assigned to.  Therefore, to change the first character to an S, you could
  147.     do this:
  148.  
  149.     substr($var,0,1) = 'S';
  150.  
  151.     This assumes that $[ is 0;  for a library routine where you can't know $[,
  152.     you should use this instead:
  153.  
  154.     substr($var,$[,1) = 'S';
  155.  
  156.     While it would be slower, you could in this case use a substitute:
  157.  
  158.     $var =~ s/^./S/;
  159.  
  160.     But this won't work if the string is empty or its first character is a
  161.     newline, which "." will never match.  So you could use this instead:
  162.  
  163.     $var =~ s/^[^\0]?/S/;
  164.  
  165.     To do things like translation of the first part of a string, use substr,
  166.     as in:
  167.  
  168.     substr($var, $[, 10) =~ tr/a-z/A-Z/;
  169.  
  170.     If you don't know then length of what to translate, something like
  171.     this works:
  172.  
  173.     /^(\S+)/ && substr($_,$[,length($1)) =~ tr/a-z/A-Z/;
  174.  
  175.     For some things it's convenient to use the /e switch of the
  176.     substitute operator:
  177.  
  178.     s/^(\S+)/($tmp = $1) =~ tr#a-z#A-Z#, $tmp/e
  179.  
  180.     although in this case, it runs more slowly than does the previous example.
  181.  
  182.  
  183. 2.14) How can I manipulate fixed-record-length files?
  184.  
  185.     The most efficient way is using pack and unpack.  This is faster than
  186.     using substr.  Here is a sample chunk of code to break up and put back
  187.     together again some fixed-format input lines, in this case, from ps.
  188.  
  189.     # sample input line:
  190.     #   15158 p5  T      0:00 perl /mnt/tchrist/scripts/now-what
  191.     $ps_t = 'A6 A4 A7 A5 A*';
  192.     open(PS, "ps|");
  193.     $_ = <PS>; print;
  194.     while (<PS>) {
  195.         ($pid, $tt, $stat, $time, $command) = unpack($ps_t, $_);
  196.         for $var ('pid', 'tt', 'stat', 'time', 'command' ) {
  197.         print "$var: <", eval "\$$var", ">\n";
  198.         }
  199.         print 'line=', pack($ps_t, $pid, $tt, $stat, $time, $command),  "\n";
  200.     }
  201.  
  202.  
  203. 2.15) How can I make a file handle local to a subroutine?
  204.  
  205.     You must use the type-globbing *VAR notation.  Here is some code to
  206.     cat an include file, calling itself recursively on nested local
  207.     include files (i.e. those with #include "file", not #include <file>):
  208.  
  209.     sub cat_include {
  210.         local($name) = @_;
  211.         local(*FILE);
  212.         local($_);
  213.  
  214.         warn "<INCLUDING $name>\n";
  215.         if (!open (FILE, $name)) {
  216.         warn "can't open $name: $!\n";
  217.         return;
  218.         }
  219.         while (<FILE>) {
  220.         if (/^#\s*include "([^"]*)"/) {
  221.             &cat_include($1);
  222.         } else {
  223.             print;
  224.         }
  225.         }
  226.         close FILE;
  227.     }
  228.  
  229.  
  230. 2.16) How can I extract just the unique elements of an array?
  231.  
  232.     There are several possible ways, depending on whether the
  233.     array is ordered and you wish to preserve the ordering.
  234.  
  235.     a) If @in is sorted, and you want @out to be sorted:
  236.  
  237.     $prev = 'nonesuch';
  238.     @out = grep($_ ne $prev && (($prev) = $_), @in);
  239.  
  240.        This is nice in that it doesn't use much extra memory,
  241.        simulating uniq's behavior of removing only adjacent
  242.        duplicates.
  243.  
  244.     b) If you don't know whether @in is sorted:
  245.  
  246.     undef %saw;
  247.     @out = grep(!$saw{$_}++, @in);
  248.  
  249.     c) Like (b), but @in contains only small integers:
  250.  
  251.     @out = grep(!$saw[$_]++, @in);
  252.  
  253.     d) A way to do (b) without any loops or greps:
  254.  
  255.     undef %saw;
  256.     @saw{@in} = ();
  257.     @out = sort keys %saw;  # remove sort if undesired
  258.  
  259.     e) Like (d), but @in contains only small positive integers:
  260.  
  261.     undef @ary;
  262.     @ary[@in] = @in;
  263.     @out = sort @ary;
  264.  
  265.  
  266. 2.17) How can I call alarm() or usleep() from Perl?
  267.  
  268.     It's available as a built-in as of version 3.038.  If you want finer
  269.     granularity than 1 second (as usleep() provides) and have itimers and
  270.     syscall() on your system, you can use the following.  You could also
  271.     use select().
  272.  
  273.     It takes a floating-point number representing how long to delay until
  274.     you get the SIGALRM, and returns a floating- point number representing
  275.     how much time was left in the old timer, if any.  Note that the C
  276.     function uses integers, but this one doesn't mind fractional numbers.
  277.  
  278.     # alarm; send me a SIGALRM in this many seconds (fractions ok)
  279.     # tom christiansen <tchrist@convex.com>
  280.     sub alarm {
  281.     require 'syscall.ph';
  282.     require 'sys/time.ph';
  283.  
  284.     local($ticks) = @_;
  285.     local($in_timer,$out_timer);
  286.     local($isecs, $iusecs, $secs, $usecs);
  287.  
  288.     local($itimer_t) = 'L4'; # should be &itimer'typedef()
  289.  
  290.     $secs = int($ticks);
  291.     $usecs = ($ticks - $secs) * 1e6;
  292.  
  293.     $out_timer = pack($itimer_t,0,0,0,0);
  294.     $in_timer  = pack($itimer_t,0,0,$secs,$usecs);
  295.  
  296.     syscall(&SYS_setitimer, &ITIMER_REAL, $in_timer, $out_timer)
  297.         && die "alarm: setitimer syscall failed: $!";
  298.  
  299.     ($isecs, $iusecs, $secs, $usecs) = unpack($itimer_t,$out_timer);
  300.     return $secs + ($usecs/1e6);
  301.     }
  302.  
  303.  
  304. 2.18) How can I test whether an array contains a certain element?
  305.  
  306.     There are several ways to approach this.  If you are going to make
  307.     this query many times and the values are arbitrary strings, the
  308.     fastest way is probably to invert the original array and keep an
  309.     associative array lying about whose keys are the first array's values.
  310.  
  311.     @blues = ('turquoise', 'teal', 'lapis lazuli');
  312.     undef %is_blue;
  313.     for (@blues) { $is_blue{$_} = 1; }
  314.  
  315.     Now you can check whether $is_blue{$some_color}.  It might have been
  316.     a good idea to keep the blues all in an assoc array in the first place.
  317.  
  318.     If the values are all small integers, you could use a simple
  319.     indexed array.  This kind of an array will take up less space:
  320.  
  321.     @primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
  322.     undef @is_tiny_prime;
  323.     for (@primes) { $is_tiny_prime[$_] = 1; }
  324.  
  325.     Now you check whether $is_tiny_prime[$some_number].
  326.  
  327.     If the values in question are integers, but instead of strings,
  328.     you can save quite a lot of space by using bit strings instead:
  329.  
  330.     @articles = ( 1..10, 150..2000, 2017 );
  331.     undef $read;
  332.     grep (vec($read,$_,1) = 1, @articles);
  333.  
  334.     Now check whether vec($read,$n,1) is true for some $n.
  335.  
  336.  
  337. 2.19) How can I do an atexit() or setjmp()/longjmp() in Perl?
  338.  
  339.     Perl's exception-handling mechanism is its eval operator.  You
  340.     can use eval as setjmp and die as longjmp.  Here's an example
  341.     of Larry's for timed-out input, which in C is often implemented
  342.     using setjmp and longjmp:
  343.  
  344.       $SIG{ALRM} = TIMEOUT;
  345.       sub TIMEOUT { die "restart input\n" }
  346.  
  347.       do { eval { &realcode } } while $@ =~ /^restart input/;
  348.  
  349.       sub realcode {
  350.           alarm 15;
  351.           $ans = <STDIN>;
  352.           alarm 0;
  353.       }
  354.  
  355.    Here's an example of Tom's for doing atexit() handling:
  356.  
  357.     sub atexit { push(@_exit_subs, @_) }
  358.  
  359.     sub _cleanup { unlink $tmp }
  360.  
  361.     &atexit('_cleanup');
  362.  
  363.     eval <<'End_Of_Eval';  $here = __LINE__;
  364.     # as much code here as you want
  365.     End_Of_Eval
  366.  
  367.     $oops = $@;  # save error message
  368.  
  369.     # now call his stuff
  370.     for (@_exit_subs) { &$_() }
  371.  
  372.     $oops && ($oops =~ s/\(eval\) line (\d+)/$0 .
  373.         " line " . ($1+$here)/e, die $oops);
  374.  
  375.     You can register your own routines via the &atexit function now.  You
  376.     might also want to use the &realcode method of Larry's rather than
  377.     embedding all your code in the here-is document.  Make sure to leave
  378.     via die rather than exit, or write your own &exit routine and call
  379.     that instead.   In general, it's better for nested routines to exit
  380.     via die rather than exit for just this reason.
  381.  
  382.     Eval is also quite useful for testing for system dependent features,
  383.     like symlinks, or using a user-input regexp that might otherwise
  384.     blowup on you.
  385.  
  386.  
  387. 2.20) Why doesn't Perl interpret my octal data octally?
  388.  
  389.     Perl only understands octal and hex numbers as such when they occur
  390.     as constants in your program.  If they are read in from somewhere
  391.     and assigned, then no automatic conversion takes place.  You must
  392.     explicitly use oct() or hex() if you want this kind of thing to happen.
  393.     Actually, oct() knows to interpret both hex and octal numbers, while
  394.     hex only converts hexadecimal ones.  For example:
  395.  
  396.     {
  397.         print "What mode would you like? ";
  398.         $mode = <STDIN>;
  399.         $mode = oct($mode);
  400.         unless ($mode) {
  401.         print "You can't really want mode 0!\n";
  402.         redo;
  403.         }
  404.         chmod $mode, $file;
  405.     }
  406.  
  407.     Without the octal conversion, a requested mode of 755 would turn
  408.     into 01363, yielding bizarre file permissions of --wxrw--wt.
  409.  
  410.     If you want something that handles decimal, octal and hex input,
  411.     you could follow the suggestion in the man page and use:
  412.  
  413.     $val = oct($val) if $val =~ /^0/;
  414.  
  415. 2.21) How do I sort an associative array by value instead of by key?
  416.  
  417.     You have to declare a sort subroutine to do this.  Let's assume
  418.     you want an ASCII sort on the values of the associative array %ary.
  419.     You could do so this way:
  420.  
  421.     foreach $key (sort by_value keys %ary) {
  422.         print $key, '=', $ary{$key}, "\n";
  423.     }
  424.     sub by_value { $ary{$a} cmp $ary{$b}; }
  425.  
  426.     If you wanted a descending numeric sort, you could do this:
  427.  
  428.     sub by_value { $ary{$b} <=> $ary{$a}; }
  429.  
  430.     You can also inline your sort function, like this:
  431.  
  432.     foreach $key ( sort { $ary{$b} <=> $ary{$a} } keys %ary ) {
  433.         print $key, '=', $ary{$key}, "\n";
  434.     }
  435.  
  436.     If you wanted a function that didn't have the array name hard-wired
  437.     into it, you could so this:
  438.  
  439.     foreach $key (&sort_by_value(*ary)) {
  440.         print $key, '=', $ary{$key}, "\n";
  441.     }
  442.     sub sort_by_value {
  443.         local(*x) = @_;
  444.         sub _by_value { $x{$a} cmp $x{$b}; }
  445.         sort _by_value keys %x;
  446.     }
  447.  
  448.     If you want neither an alphabetic nor a numeric sort, then you'll
  449.     have to code in your own logic instead of relying on the built-in
  450.     signed comparison operators "cmp" and "<=>".
  451.  
  452.     Note that if you're sorting on just a part of the value, such as a
  453.     piece you might extract via split, unpack, pattern-matching, or
  454.     substr, then rather than performing that operation inside your sort
  455.     routine on each call to it, it is significantly more efficient to
  456.     build a parallel array of just those portions you're sorting on, sort
  457.     the indices of this parallel array, and then to subscript your original
  458.     array using the newly sorted indices.  This method works on both
  459.     regular and associative arrays, since both @ary[@idx] and @ary{@idx}
  460.     make sense.  See page 245 in the Camel Book on "Sorting an Array by a
  461.     Computable Field" for a simple example of this.
  462.  
  463.  
  464. 2.22) How can I capture STDERR from an external command?
  465.  
  466.     There are three basic ways of running external commands:
  467.  
  468.     system $cmd;
  469.     $output = `$cmd`;
  470.     open (PIPE, "cmd |");
  471.  
  472.     In the first case, both STDOUT and STDERR will go the same place as
  473.     the script's versions of these, unless redirected.  You can always put
  474.     them where you want them and then read them back when the system
  475.     returns.  In the second and third cases, you are reading the STDOUT
  476.     *only* of your command.  If you would like to have merged STDOUT and
  477.     STDERR, you can use shell file-descriptor redirection to dup STDERR to
  478.     STDOUT:
  479.  
  480.     $output = `$cmd 2>&1`;
  481.     open (PIPE, "cmd 2>&1 |");
  482.  
  483.     Another possibility is to run STDERR into a file and read the file
  484.     later, as in
  485.  
  486.     $output = `$cmd 2>some_file`;
  487.     open (PIPE, "cmd 2>some_file |");
  488.  
  489.     Here's a way to read from both of them and know which descriptor
  490.     you got each line from.  The trick is to pipe only STDERR through
  491.     sed, which then marks each of its lines, and then sends that
  492.     back into a merged STDOUT/STDERR stream, from which your Perl program
  493.     then reads a line at a time:
  494.  
  495.         open (CMD,
  496.           "3>&1 (cmd args 2>&1 1>&3 3>&- | sed 's/^/STDERR:/' 3>&-) 3>&- |");
  497.  
  498.         while (<CMD>) {
  499.           if (s/^STDERR://)  {
  500.               print "line from stderr: ", $_;
  501.           } else {
  502.               print "line from stdout: ", $_;
  503.           }
  504.         }
  505.  
  506.     Be apprised that you *must* use Bourne shell redirection syntax
  507.     here, not csh!  In fact, you can't even do these things with csh.
  508.     For details on how lucky you are that perl's system() and backtick
  509.     and pipe opens all use Bourne shell, fetch the file from convex.com
  510.     called /pub/csh.whynot -- and you'll be glad that perl's shell
  511.     interface is the Bourne shell.
  512.  
  513.  
  514. 2.23) Why doesn't open return an error when a pipe open fails?
  515.  
  516.     These statements:
  517.  
  518.     open(TOPIPE, "|bogus_command") || die ...
  519.     open(FROMPIPE, "bogus_command|") || die ...
  520.  
  521.     will not fail just for lack of the bogus_command.  They'll only
  522.     fail if the fork to run them fails, which is seldom the problem.
  523.  
  524.     If you're writing to the TOPIPE, you'll get a SIGPIPE if the child
  525.     exits prematurely or doesn't run.  If you are reading from the
  526.     FROMPIPE, you need to check the close() to see what happened.
  527.  
  528.     If you want an answer sooner than pipe buffering might otherwise
  529.     afford you, you can do something like this:
  530.  
  531.     $kid = open (PIPE, "bogus_command |");   # XXX: check defined($kid)
  532.     (kill 0, $kid) || die "bogus_command failed";
  533.  
  534.     This works fine if bogus_command doesn't have shell metas in it, but
  535.     if it does, the shell may well not have exited before the kill 0.  You
  536.     could always introduce a delay:
  537.  
  538.     $kid = open (PIPE, "bogus_command </dev/null |");
  539.     sleep 1;
  540.     (kill 0, $kid) || die "bogus_command failed";
  541.  
  542.     but this is sometimes undesirable, and in any event does not guarantee
  543.     correct behavior.  But it seems slightly better than nothing.
  544.  
  545.     Similar tricks can be played with writable pipes if you don't wish to
  546.     catch the SIGPIPE.
  547.  
  548.  
  549. 2.24) How can I compare two date strings?
  550.  
  551.     If the dates are in an easily parsed, predetermined format, then you
  552.     can break them up into their component parts and call &timelocal from
  553.     the distributed perl library.  If the date strings are in arbitrary
  554.     formats, however, it's probably easier to use the getdate program
  555.     from the Cnews distribution, since it accepts a wide variety of dates.
  556.     Note that in either case the return values you will really be
  557.     comparing will be the total time in seconds as return by time().
  558.  
  559.     Here's a getdate function for perl that's not very efficient; you
  560.     can do better this by sending it many dates at once or modifying
  561.     getdate to behave better on a pipe.  Beware the hardcoded pathname.
  562.  
  563.     sub getdate {
  564.         local($_) = shift;
  565.  
  566.         s/-(\d{4})$/+$1/ || s/\+(\d{4})$/-$1/;
  567.         # getdate has broken timezone sign reversal!
  568.  
  569.         $_ = `/usr/local/lib/news/newsbin/getdate '$_'`;
  570.         chop;
  571.         $_;
  572.     }
  573.  
  574.     Richard Ohnemus <rick@IMD.Sterling.COM> actually has a getdate.y
  575.     for use with the Perl yacc.  You can get this from ftp.sterling.com
  576.     [192.124.9.1] in /local/perl-byacc1.8.1.tar.Z, or send the author
  577.     mail for details.
  578.  
  579.  
  580. 2.25) What's the fastest way to code up a given task in perl?
  581.  
  582.     Because Perl so lends itself to a variety of different approaches
  583.     for any given task, a common question is which is the fastest way
  584.     to code a given task.  Since some approaches can be dramatically
  585.     more efficient that others, it's sometimes worth knowing which is
  586.     best.  Unfortunately, the implementation that first comes to mind,
  587.     perhaps as a direct translation from C or the shell, often yields
  588.     suboptimal performance.  Not all approaches have the same results
  589.     across different hardware and software platforms.  Furthermore,
  590.     legibility must sometimes be sacrificed for speed.
  591.  
  592.     While an experienced perl programmer can sometimes eye-ball the code
  593.     and make an educated guess regarding which way would be fastest,
  594.     surprises can still occur.  So, in the spirit of perl programming
  595.     being an empirical science, the best way to find out which of several
  596.     different methods runs the fastest is simply to code them all up and
  597.     time them. For example:
  598.  
  599.     $COUNT = 10_000; $| = 1;
  600.  
  601.     print "method 1: ";
  602.  
  603.         ($u, $s) = times;
  604.         for ($i = 0; $i < $COUNT; $i++) {
  605.         # code for method 1
  606.         }
  607.         ($nu, $ns) = times;
  608.         printf "%8.4fu %8.4fs\n", ($nu - $u), ($ns - $s);
  609.  
  610.     print "method 2: ";
  611.  
  612.         ($u, $s) = times;
  613.         for ($i = 0; $i < $COUNT; $i++) {
  614.         # code for method 2
  615.         }
  616.         ($nu, $ns) = times;
  617.         printf "%8.4fu %8.4fs\n", ($nu - $u), ($ns - $s);
  618.  
  619.     For more specific tips, see the section on Efficiency in the
  620.     ``Other Oddments'' chapter at the end of the Camel Book.
  621.  
  622.  
  623. 2.26) How can I know how many entries are in an associative array?
  624.  
  625.     While the number of elements in a @foobar array is simply @foobar when
  626.     used in a scalar, you can't figure out how many elements are in an
  627.     associative array in an analogous fashion.  That's because %foobar in
  628.     a scalar context returns the ratio (as a string) of number of buckets
  629.     filled versus the number allocated.  For example, scalar(%ENV) might
  630.     return "20/32".  While perl could in theory keep a count, this would
  631.     break down on associative arrays that have been bound to dbm files.
  632.  
  633.     However, while you can't get a count this way, one thing you *can* use
  634.     it for is to determine whether there are any elements whatsoever in
  635.     the array, since "if (%table)" is guaranteed to be false if nothing
  636.     has ever been stored in it.
  637.  
  638.     So you either have to keep your own count around and increments
  639.     it every time you store a new key in the array, or else do it
  640.     on the fly when you really care, perhaps like this:
  641.  
  642.     $count++ while each %ENV;
  643.  
  644.     This preceding method will be faster than extracting the
  645.     keys into a temporary array to count them.
  646.  
  647.     As of a very recent patch, you can say
  648.  
  649.     $count = keys %ENV;
  650.  
  651.  
  652.  
  653. 2.27) Why can't my perl program read from STDIN after I gave it ^D (EOF) ?
  654.  
  655.     Because some stdio's set error and eof flags that need clearing.
  656.  
  657.     Try keeping around the seekpointer and go there, like this:
  658.      $where = tell(LOG);
  659.      seek(LOG, $where, 0);
  660.  
  661.     If that doesn't work, try seeking to a different part of the file and
  662.     then back.  If that doesn't work, try seeking to a different part of
  663.     the file, reading something, and then seeking back.  If that doesn't
  664.     work, give up on your stdio package and use sysread.  You can't call
  665.     stdio's clearerr() from Perl, so if you get EINTR from a signal
  666.     handler, you're out of luck.  Best to just use sysread() from the
  667.     start for the tty.
  668.  
  669.  
  670. 2.28) Do I always/never have to quote my strings or use semicolons?
  671.  
  672.     You don't have to quote strings that can't mean anything else
  673.     in the language, like identifiers with any upper-case letters
  674.     in them.  Therefore, it's fine to do this:
  675.  
  676.     $SIG{INT} = Timeout_Routine;
  677.     or
  678.  
  679.     @Days = (Sun, Mon, Tue, Wed, Thu, Fri, Sat, Sun);
  680.  
  681.     but you can't get away with this:
  682.  
  683.     $foo{while} = until;
  684.  
  685.     in place of
  686.  
  687.     $foo{'while'} = 'until';
  688.  
  689.     The requirements on semicolons have been increasingly relaxed.  You no
  690.     longer need one at the end of a block, but stylistically, you're
  691.     better to use them if you don't put the curly brace on the same line:
  692.  
  693.     for (1..10) { print }
  694.  
  695.     is ok, as is
  696.  
  697.     @nlist = sort { $a <=> $b } @olist;
  698.  
  699.     but you probably shouldn't do this:
  700.     
  701.     for ($i = 0; $i < @a; $i++) {
  702.         print "i is $i\n"  # <-- oops!
  703.     }
  704.  
  705.     because you might want to add lines later, and anyway,
  706.     it looks funny. :-)
  707.  
  708.  
  709. 2.29) How can I translate tildes in a filename?
  710.  
  711.     Perl doesn't expand tildes -- the shell (ok, some shells) do.
  712.     The classic request is to be able to do something like:
  713.  
  714.     open(FILE, "~/dir1/file1");
  715.     open(FILE, "~tchrist/dir1/file1");
  716.  
  717.     which doesn't work.  (And you don't know it, because you
  718.     did a system call without an "|| die" clause! :-)
  719.  
  720.     If you *know* you're on a system with the csh, and you *know*
  721.     that Larry hasn't internalized file globbing, then you could
  722.     get away with
  723.  
  724.     $filename = <~tchrist/dir1/file1>;
  725.  
  726.     but that's pretty iffy.
  727.  
  728.     A better way is to do the translation yourself, as in:
  729.  
  730.     $filename =~ s#^~(\w+)(/.*)?$#(getpwnam($1))[7].$2#e;
  731.  
  732.     More robust and efficient versions that checked for error conditions,
  733.     handed simple ~/blah notation, and cached lookups are all reasonable
  734.     enhancements.
  735.  
  736.  
  737. 2.30) How can I convert my shell script to Perl?
  738.  
  739.     Larry's standard answer for this is to send your script to me (Tom
  740.     Christiansen) with appropriate supplications and offerings.  :-(
  741.     That's because there's no automatic machine translator.  Even if you
  742.     were, you wouldn't gain a lot, as most of the external programs would
  743.     still get called.  It's the same problem as blind translation into C:
  744.     you're still apt to be bogged down by exec()s.  You have to analyze
  745.     the dataflow and algorithm and rethink it for optimal speedup.  It's
  746.     not uncommon to see one, two, or even three orders of magnitude of
  747.     speed difference between the brute-force and the recoded approaches.
  748.  
  749.  
  750. 2.31) What is variable suicide and how can I prevent it?
  751.  
  752.     Variable suicide is a nasty sideeffect of dynamic scoping and
  753.     the way variables are passed by reference.  If you say
  754.  
  755.     $x = 17;
  756.     &munge($x);
  757.     sub munge {
  758.         local($x);
  759.         local($myvar) = $_[0];
  760.         ...
  761.     }
  762.  
  763.     Then you have just clubbered $_[0]!  Why this is occurring
  764.     is pretty heavy wizardry: the reference to $x stored in
  765.     $_[0] was temporarily occluded by the previous local($x)
  766.     statement (which, you're recall, occurs at run-time, not
  767.     compile-time).  The work around is simple, however: declare
  768.     your formal parameters first:
  769.  
  770.     sub munge {
  771.         local($myvar) = $_[0];
  772.         local($x);
  773.         ...
  774.     }
  775.  
  776.     That doesn't help you if you're going to be trying to access
  777.     @_ directly after the local()s.  In this case, careful use
  778.     of the package facility is your only recourse.
  779.  
  780.     Another manifestation of this problem occurs due to the
  781.     magical nature of the index variable in a foreach() loop.
  782.  
  783.     @num = 0 .. 4;
  784.     print "num begin  @num\n";
  785.     foreach $m (@num) { &ug }
  786.     print "num finish @num\n";
  787.     sub ug {
  788.         local($m) = 42;
  789.         print "m=$m  $num[0],$num[1],$num[2],$num[3]\n";
  790.     }
  791.  
  792.     Which prints out the mysterious:
  793.  
  794.     num begin  0 1 2 3 4
  795.     m=42  42,1,2,3
  796.     m=42  0,42,2,3
  797.     m=42  0,1,42,3
  798.     m=42  0,1,2,42
  799.     m=42  0,1,2,3
  800.     num finish 0 1 2 3 4
  801.  
  802.     What's happening here is that $m is an alias for each
  803.     element of @num.  Inside &ug, you temporarily change
  804.     $m.  Well, that means that you've also temporarily
  805.     changed whatever $m is an alias to!!  The only workaround
  806.     is to be careful with global variables, using packages,
  807.     and/or just be aware of this potential in foreach() loops.
  808.  
  809.  
  810. 2.32) Can I use Perl regular expressions to match balanced text?
  811.  
  812.     No, or at least, not by the themselves.
  813.  
  814.     Regexps just aren't powerful enough.  Although Perl's patterns aren't
  815.     strictly regular because they do backtracking (the \1 notation), you
  816.     still can't do it.  You need to employ auxiliary logic.  A simple
  817.     approach would involve keeping a bit of state around, something
  818.     vaguely like this (although we don't handle patterns on the same line):
  819.  
  820.     while(<>) {
  821.         if (/pat1/) {
  822.         if ($inpat++ > 0) { warn "already saw pat1" }
  823.         redo;
  824.         }
  825.         if (/pat2/) {
  826.         if (--$inpat < 0) { warn "never saw pat1" }
  827.         redo;
  828.         }
  829.     }
  830.  
  831.     A rather more elaborate subroutine to pull out balanced and possibly
  832.     nested single chars, like ` and ', { and }, or ( and ) can be found
  833.     on convex.com in /pub/perl/scripts/pull_quotes.
  834.  
  835.  
  836. 2.33) Can I use Perl to run a telnet or ftp session?
  837.  
  838.     Sure, you can connect directly to them using sockets, or you can run a
  839.     session on a pty.  In either case, Randal's chat2 package, which is
  840.     distributed with the perl source, will come in handly.  It address
  841.     much the same problem space as Don Libes's expect package does.  Two
  842.     examples of using managing an ftp session using chat2 can be found on
  843.     convex.com in /pub/perl/scripts/ftp-chat2.shar .
  844.